package com.kang.c0c.optimize;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Vector;

import com.kang.c0c.symbol.Symbol;
import com.kang.c0c.tree.node.BinaryNode;
import com.kang.c0c.tree.node.LeafNode;
import com.kang.c0c.tree.node.Node;

/**
 * 寄存器地址描述符，存储具体寄存器当前存储着什么节点的值
 * HashSet内虽然存储的是Object对象，但其实它只存放了两类对象
 * 一类是Symbol，针对用户显示声明的变量（即在符号表中有存储的变量）
 * 一类是BinaryNode，针对抽象语法数的操作并可能生成临时变量的节点
 * 
 * @author kang
 *
 */
public class Reg{
	String reg;
	int id;
	private HashSet<Object> state;
	
	public static Reg regs[] = {new Reg("None",0),
			new Reg("EBX",1), new Reg("EDI",2), new Reg("ESI",3),
			new Reg("EAX",4), new Reg("ECX",5), new Reg("EDX",6)};
	
	public Reg(String reg,int id){
		this.reg = reg;
		this.id = id;
		state = new HashSet<Object>();
	}
	
	public String getReg(){
		return reg;
	}
	
	public void add(Object node, boolean stored){
		Object ob = null;
		Address addr;
		
		if(node instanceof Symbol){
			addr = ((Symbol)node).addr;
			if(addr == null){
				addr = new Address();
				((Symbol)node).addr = addr;
			}
			ob = node;
		}else if(node instanceof LeafNode){
			ob = ((LeafNode)node).getValue();
			addr = ((Symbol)ob).addr;
			if(addr == null){
				addr = new Address();
				((Symbol)ob).addr = addr;
			}
		}else if(node instanceof BinaryNode){
			ob = node;
			addr = ((BinaryNode)ob).addr;
			if(addr == null){
				addr = new Address();
				((BinaryNode)ob).addr = addr;
			}
		}else
			return;
		
		if(addr.getReg() >= 0){
			regs[addr.getReg()].remove(node);
		}
		addr.setReg(id);
		addr.setStored(stored);
		state.add(ob);
	}
	
	public void add(Object node){
		add(node,false);
	}
	
	public boolean contains(Node node){
		Object ob = null;
		if(node instanceof LeafNode){
			ob = (Symbol)((LeafNode)node).getValue();
		}else if(node instanceof BinaryNode){
			ob = node;
		}
		
		if(ob == null)
			return false;
		
		return state.contains(ob);
	}
	
	public boolean remove(Object node){
		Object ob = node;
		Address addr;
		if(node instanceof Symbol){
			ob = node;
			addr = ((Symbol)ob).addr;
		}else if(node instanceof LeafNode){
			ob = ((LeafNode)node).getValue();
			addr = ((Symbol)ob).addr;			
		}else if(node instanceof BinaryNode){
			ob = node;
			addr = ((BinaryNode)node).addr;
		}else
			return false;
		
		if(addr.getReg() != id)
			return false;
		addr.setReg(-1);
		
		return state.remove(ob);
	}
	
	public void clear(){
		Iterator<Object> it = state.iterator();
		Vector<Object> v = new Vector<Object>();
		
		int size = 0;
		while(it.hasNext()){
			Object ob = it.next();
			v.add(ob);
			size ++;
		}
		
		while(size > 0){
			size--;
			remove(v.elementAt(size));
		}
		state.clear();		
	}
	
	public Iterator<Object> iterator(){
		return state.iterator();
	}
	
	public int size(){
		return state.size();
	}

	public int getId() {
		return id;
	}
}
